﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using XMLGener.Utils;

namespace XMLGener.Data
{
    /// <summary>
    /// 
    /// </summary>
    public class XMLGenerAttribute:XMLGenerNode
    {
        /// <summary>
        /// 
        /// </summary>
        private XMLGenerAttribute()
            : base()
        {}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="parent"></param>
        public XMLGenerAttribute(String name, XMLGenerElement parent)
        {
            defaultInitialization();
            this.parentNode = parent;
            if (parentNode != null)
                this.parentNode.addChildNode(this);
            XmlElement parentXml = parent.xmlElem;
            if (parentXml == null)
            {
                logger.addErrorLog(this.GetType().ToString(),"XMLGenerNode \""+parentNode.name+"\" has not assigned xml node.");
            }
            XmlElement attributesXML= XMLUtils.getSubElement(parentXml,XATTRIBUTES_STR);
            if (attributesXML == null)
            {
                attributesXML = parentXml.OwnerDocument.CreateElement(XATTRIBUTES_STR);
                parentXml.AppendChild(attributesXML);
            }

            this.xmlElem = attributesXML.OwnerDocument.CreateElement(nodeTypeStr);
            this.name = name;
            attributesXML.AppendChild(xmlElem);
            this.xtype = XNodeType.ATTRIBUTE;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="xmlElem"></param>
        public XMLGenerAttribute(XMLGenerElement parent, XmlElement xmlElem)
        {
            defaultInitialization();
            this.xtype = XNodeType.ATTRIBUTE;
            this.parentNode = parent;
            if (parentNode != null)
                this.parentNode.addChildNode(this);
            this.xmlElem = xmlElem;
            //this.name = xmlElem.GetAttribute("name");
        }

        /// <summary>
        /// 
        /// </summary>
        protected override void defaultInitialization()
        {
            base.defaultInitialization();
            this.nodeTypeStr = XMLGenerNode.XATTRIBUTE_STR;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="node"></param>
        public override void addChildNode(XMLGenerNode node)
        {
            return;
        }

        /// <summary>
        /// Return avialable types for this type of node
        /// </summary>
        /// <returns>list of strings</returns>
        public override XDataTypeCollection listAvailabeTypes()
        {
            if (this.ownerDocument != null)
                return this.ownerDocument.getAllDataTypes();
            return XMLGenerDataTypes.getDefaultTypes();           
        }

        public override XMLGenerNode getCopy(int depth)
        {
            XMLGenerAttribute result = new XMLGenerAttribute(null, this.xmlElem);
            result.originalNode = this;
            result._isCopy = true;
            return result;
        }

        //---------------------------
        // generating 
        //---------------------------

        /// <summary>
        /// 
        /// </summary>
        public override bool initModule()
        {
            if (modInst != null)
                return true;
            if (this.module == null)
            {
                logger.addLog(this.GetType().ToString(),"Attribute "+this.name+" (under element "+parentNode.name+") has not defined generator module.");
                return true;
            }
            this.modInst = XModuleManager.getModuleInstance(this.module);
            if (this.modInst == null)
                return false;
            if (settingsElement != null)
            {
                try
                {
                    this.modInst.setParameters(getSettingsForModule(),ownerDocument);
                }
                catch (Exception e)
                {
                    logger.addErrorLog(this.GetType().ToString() + ", attribute:" + this.name + ", setting attributes for module " + this.module, "Error:" + e.Message);
                    return false;
                }
            }
            return true;
        }
        private string getSettingsForModule()
        {
            string result = "";
            if (settingsElement != null)
                result = settingsElement.OuterXml;
            if (this.ownerDocument != null)
                result = result + this.ownerDocument.getRestictionForDataType(this.contentType);


            return "<modulesettings>" + result + "</modulesettings>";
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override string getGeneratedString()
        {
            if (this.modInst == null)
                return null;
            return modInst.generate();
        }


    }
}
